/*
 * GramaticaControl.h
 *
 *  Created on: 23/11/2012
 *      Author: vagner
 */

#ifndef GRAMATICACONTROL_H_
#define GRAMATICACONTROL_H_
#include "GramaticaModel.h"

using namespace tp2ftcModel;

namespace tp2ftcControl {

class GramaticaControl {

private:
	static const char LEFT_PAR = '<';
	static const char RIGHT_PAR = '>';
	static const std::string SINAL_IGUAL;
	static const char ABRE_ASPAS = '\"';
	static const char FECHA_ASPAS = '\"';
	static const char ESPACO_BRANCO = ' ';

	GramaticaModel gramaticaModel;
	/*Verifica se entrada do usuario esta conforme a sintaxe de uma variavel (<P>)
	 * retornando true se for verdade
	 */
	bool validaSintaxeVariavel(const std::string& entradaUsuario);
	/*Verifica se entrada do usuario esta conforme a sintaxe de uma regra (R ::= w, onde w contem variaveis e terminais)
	 * retornando true se for verdade
	 */
	bool validaSintaxeRegra(const std::string& entradaUsuario);
	//Verifica a sintaxa de um terminal que não inicial com o caractere '"'(ASPAS)
	bool validaSintaxeTerminal(const std::string& entradaUsuario);
	void copiaFromIndex(int& inicio, int& fim, std::string& origem, std::string& destino);
	//Remove possiveis espacos em branco antes e depois de um inicializador '<' e um terminador '>' de uma variavel;
	void removeEspacoEmBranco(std::string& variavel);
	bool buscaItem(const std::vector<std::string>& lista,const std::string& item) const;
	bool geraPalavra(const std::vector<std::string>& pseudoTerminal, const std::vector<std::string>& ladoDireito)const;
	bool isAlcancavel(const std::vector<variavel>& pseudoVar,const std::string& var,const std::vector<std::string>& ladoDireito) const;
	//Retorna os elementos de v1 que NÃO estão em v2
	std::vector<variavel> vDiferenca(const std::vector<variavel>& v1,const std::vector<variavel>& v2)const;

public:
	GramaticaControl();
	virtual ~GramaticaControl();
	std::string defineVariavelPartida(std::string& entradaUsuario);
	std::string insereRegra(std::string& entradaUsuario);
	std::string removeRegra(const std::string& entradaUsuario);
	std::string removeVariavel(const std::string& entradaUsuario);
	std::vector<variavel> recuperaVariaveisInuteis(const std::vector<variavel>& variaveisNaoInuteis)const;
	std::string recuperaVariavelPartida()const;
	std::vector<regra> recuperaRegras()const;
	std::vector<variavel> recuperaVariaveisGeramPalavras(void);
	std::vector<variavel> recuperaVariaveisAlcancaveis(std::vector<variavel>& v1)const;
	std::vector<variavel> recuperaVariavelInutil(std::vector<variavel>& v2);
};

} /* namespace tp2ftcControl */
#endif /* GRAMATICACONTROL_H_ */
